# coding:utf-8
import util;

class VirtualDevice:
    
    VIRTUAL_DEV_DISK = "disk"
    VIRTUAL_DEV_NET = "interface"
    VIRTUAL_DEV_INPUT = "input"
    VIRTUAL_DEV_GRAPHICS = "graphics"
    VIRTUAL_DEV_AUDIO = "sound"
    VIRTUAL_DEV_HOSTDEV = "hostdev"
    VIRTUAL_DEV_SERIAL = "serial"
    VIRTUAL_DEV_PARALLEL = "parallel"
    VIRTUAL_DEV_CHANNEL = "channel"
    VIRTUAL_DEV_CONSOLE = "console"
    VIRTUAL_DEV_VIDEO = "video"
    VIRTUAL_DEV_CONTROLLER = "controller"
    VIRTUAL_DEV_WATCHDOG = "watchdog"
    VIRTUAL_DEV_FILESYSTEM = "filesystem"
    VIRTUAL_DEV_SMARTCARD = "smartcard"
    VIRTUAL_DEV_REDIRDEV = "redirdev"
    
    virtual_device_types = [VIRTUAL_DEV_DISK,
                            VIRTUAL_DEV_CONTROLLER,
                            VIRTUAL_DEV_FILESYSTEM,
                            VIRTUAL_DEV_NET,
                            VIRTUAL_DEV_INPUT,
                            VIRTUAL_DEV_GRAPHICS,
                            VIRTUAL_DEV_SERIAL,
                            VIRTUAL_DEV_PARALLEL,
                            VIRTUAL_DEV_CONSOLE,
                            VIRTUAL_DEV_CHANNEL,
                            VIRTUAL_DEV_AUDIO,
                            VIRTUAL_DEV_VIDEO,
                            VIRTUAL_DEV_HOSTDEV,
                            VIRTUAL_DEV_WATCHDOG,
                            VIRTUAL_DEV_SMARTCARD,
                            VIRTUAL_DEV_REDIRDEV]


"""
<disk > img
"""
class VirtualDisk:
    
    _virtual_device_type = VirtualDevice.VIRTUAL_DEV_DISK

    DRIVER_FILE = "file"
    DRIVER_PHY = "phy"
    DRIVER_TAP = "tap"
    DRIVER_QEMU = "qemu"
    driver_names = [DRIVER_FILE, DRIVER_PHY, DRIVER_TAP, DRIVER_QEMU]

    DRIVER_QEMU_RAW = "raw"
    DRIVER_TAP_RAW = "aio"
    DRIVER_TAP_QCOW = "qcow"
    DRIVER_TAP_QCOW2 = "qcow2"
    DRIVER_TAP_VMDK = "vmdk"
    DRIVER_TAP_VDISK = "vdisk"
    
    driver_types = [DRIVER_TAP_RAW, DRIVER_TAP_QCOW, DRIVER_TAP_QCOW2,
        DRIVER_TAP_VMDK, DRIVER_TAP_VDISK]

    CACHE_MODE_NONE = "none"
    CACHE_MODE_WRITETHROUGH = "writethrough"
    CACHE_MODE_WRITEBACK = "writeback"
    cache_types = [CACHE_MODE_NONE, CACHE_MODE_WRITETHROUGH,
        CACHE_MODE_WRITEBACK]

    DEVICE_DISK = "disk"
    DEVICE_CDROM = "cdrom"
    DEVICE_FLOPPY = "floppy"
    devices = [DEVICE_DISK, DEVICE_CDROM, DEVICE_FLOPPY]

    TYPE_FILE = "file"
    TYPE_BLOCK = "block"
    TYPE_DIR = "dir"
    types = [TYPE_FILE, TYPE_BLOCK, TYPE_DIR]

    _target_props = ["file", "dev", "dir"]

    IO_MODE_NATIVE = "native"
    IO_MODE_THREADS = "threads"
    io_modes = [IO_MODE_NATIVE, IO_MODE_THREADS]
    
    def __init__(self, file, type, devices, dev, bus="ide",
                 address_type=None, address_slot=None, address_function=None):
        
        self.file = file;
        self.type = type;
        self.devices = devices;
        self.dev = dev;
        self.bus = bus;
        
        self.address_type = address_type;
        self.address_slot = address_slot;
        self.address_function = address_function;
        
        pass
    
    def get_xml_config(self):
        xml = "";
        disk = "        <disk type='file' device='%s'>\n" % self.devices;
        xml = util.xml_append(xml, disk);
        if(self.devices != "cdrom"):        
            dirver = "            <driver name='qemu' type='%s' />\n" % self.type;
            xml = util.xml_append(xml, dirver);
                    
        source = "            <source file='%s' />\n" % self.file;
        xml = util.xml_append(xml, source);
        
        target = "            <target dev='%s' bus='%s' />\n" % (self.dev, self.bus);
        xml = util.xml_append(xml, target);
        
        if(self.devices == "cdrom"):
            xml = util.xml_append(xml, "            <readonly />\n");
        
        
        xml = util.xml_append(xml, "        </disk>\n");
        
        return xml;
        

class VirtualControl:
    
    _virtual_device_type = VirtualDevice.VIRTUAL_DEV_CONTROLLER;

    CONTROLLER_TYPE_IDE = "ide"
    CONTROLLER_TYPE_FDC = "fdc"
    CONTROLLER_TYPE_SCSI = "scsi"
    CONTROLLER_TYPE_SATA = "sata"
    CONTROLLER_TYPE_VIRTIOSERIAL = "virtio-serial"
    CONTROLLER_TYPE_USB = "usb"
    CONTROLLER_TYPES = [CONTROLLER_TYPE_IDE, CONTROLLER_TYPE_FDC,
                        CONTROLLER_TYPE_SCSI, CONTROLLER_TYPE_SATA,
                        CONTROLLER_TYPE_VIRTIOSERIAL, CONTROLLER_TYPE_USB]
    
    def __init__(self):
        self.index = 0;        
        
    def get_xml_config(self):
        xml = "        <controller type='%s' index='%s'" % ('ide', self.index);
        xml += ">\n"        
        xml += "        </controller>\n"
        return xml
    

class VirtualInterface:
    
    def __init__(self, mac, type, network):
        self.mac = mac;
        self.type = type;
        self.network = network;        
    
    def get_xml_config(self):
        
        xml = "        <interface type='%s'>\n" % self.type;
        mac = "            <mac address='%s' />\n" % self.mac;
        source = "            <source network='%s' />\n" % self.network;
        
        
        xml = util.xml_append(xml, mac);
        xml = util.xml_append(xml, source);
        xml = util.xml_append(xml, "        </interface>\n");
        
        return xml;
        
class VirtualSerial:
    _virtual_device_type = VirtualDevice.VIRTUAL_DEV_SERIAL;
    
    def __init__(self, t, path, port):
        self.type = t;
        self.path = path;
        self.port = port;
        
    def get_xml_config(self):
        
        xml = "        <serial type='%s'>\n" % self.type;
        source = "            <source path='%s' />\n" % self.path;
        target = "            <target port='%s' />\n" % self.port;
        
        xml = util.xml_append(xml, source);
        xml = util.xml_append(xml, target);
        xml = util.xml_append(xml, "        </serial>\n");
        
        return xml;
        
        pass

class VirtualConsole:
    _virtual_device_type = VirtualDevice.VIRTUAL_DEV_CONSOLE;
    
    def __init__(self, t, tty, path, t1, port):
        self.type = t;
        self.tty = tty;
        self.path = path;
        self.t1 = t1;
        self.port = port;
    
    def get_xml_config(self):
        xml = "        <console type='%s' tty='%s' >\n" % (self.type, self.tty);
        source = "            <source path='%s' />\n" % self.path;
        target = "            <target type='%s' port='%s' />\n" % (self.t1, self.port);
        
        xml = util.xml_append(xml, source);
        xml = util.xml_append(xml, target);
        xml = util.xml_append(xml, "        </console>\n");
        
        return xml;

class VirtualGraphics:
    def __init__(self, port, listen):
        self.port = port;
        self.listen = listen;
        
    def get_xml_config(self):
        xml = "        <graphics type='vnc' port='%s' autoport='no' listen='%s'>\n" % (self.port, self.listen);
        listen = "            <listen type='address' address='%s' />\n" % self.listen;
        xml = util.xml_append(xml, listen);
        xml = util.xml_append(xml, "        </graphics>\n");
        
        return xml;

class VirtualSound:
    
    def get_xml_config(self):
        
        xml = "        <sound model='ich6'>\n"       
        xml = util.xml_append(xml, "        </sound>\n");
        
        return xml;

class VirtualVideo:
    
    def get_xml_config(self):
        xml = "        <video>\n"
        model = "            <model type='vga' vram='9216' heads='1' />\n"
        
        xml = util.xml_append(xml, model);
        
        xml = util.xml_append(xml, "        </video>\n");
        
        return xml;

class VirtualMemballoon:
    
    def get_xml_config(self):
        xml = "        <memballoon model='virtio'>\n"        
        xml = util.xml_append(xml, "        </memballoon>\n");
        
        return xml;

class Installer:
    
    _dumpxml_xpath = "/domain/os"
    def __init__(self, capabilities=None, arch=None, type=None):
        self.arch = arch;
        self.type = type;
        self.mechine = None;
        if(capabilities is not None):
            for d in capabilities.current:
                if(d.type == self.type):
                    self.mechine = d.machine[0];
                    break;
        
    def get_arch(self):
        return self.arch;
    def set_arch(self, value):
        self.arch = value;
    
    arch = property(get_arch, set_arch);
    
    def get_type(self):
        return self.type;
    def set_type(self, value):
        self.type = value;
    type = property(get_type, set_type);
    
    def get_xml_config(self):
        old = '    <os>\n';
        typexml = '        <type';
        typexml += " arch='%s'" % self.arch;
        typexml += " mechine='%s'" % self.mechine;
        typexml += ">%s</type>\n" % 'hvm';
        bootxml = "        <boot dev='cdrom' />\n"
        bootxml += "        <boot dev='hd' />\n";        
        
        oldxml = util.xml_append(old, typexml);
        osxml = util.xml_append(oldxml, bootxml);
        os = util.xml_append(osxml, "    </os>");
        
        return os;

class Device:
    
    def __init__(self, emulator, isImport, imagePath, isoPath, mac, port, listen):
        self.emulator = emulator;
        self.isimport = isImport;
        "image"
        self.imageDisk = VirtualDisk(imagePath, "qcow2", "disk", "hda");
        self.isoDisk = None;
        "iso"
        if(not isImport):
            self.isoDisk = VirtualDisk(isoPath, "raw", "cdrom", "hdc");
        
        self.control = VirtualControl();
        
        self.interface = VirtualInterface(mac, 'network', 'default');
        
        self.serial = VirtualSerial('pty', '/dev/pts/2', '0');
        
        self.console = VirtualConsole('pty', '/dev/pts/2', '/dev/pts/2', 'serial', '0');
        
        self.graphics = VirtualGraphics(port, listen);
        
        self.sound = VirtualSound();
        
        self.video = VirtualVideo();
        
        self.memballoon = VirtualMemballoon();
        
    def get_xml_config(self):
        xml = "    <devices>\n";
        
        emulator = "        <emulator>%s</emulator>\n" % self.emulator;
        
        xml = util.xml_append(xml, emulator);
        
        imgdisk = self.imageDisk.get_xml_config();
        
        xml = util.xml_append(xml, imgdisk);
        
        if(not self.isimport):
            isodisk = self.isoDisk.get_xml_config();
            xml = util.xml_append(xml, isodisk);
        
#        control = self.control.get_xml_config();
#        xml = util.xml_append(xml, control);
        
        interface = self.interface.get_xml_config();        
        xml = util.xml_append(xml, interface);
        
#        serial = self.serial.get_xml_config();
#        xml = util.xml_append(xml, serial);
#        
#        console = self.console.get_xml_config();
#        xml = util.xml_append(xml, console);
        
#        tablet = "        <input type='tablet' bus='usb'/>\n";
#        xml = util.xml_append(xml, tablet);
        
        mouse = "        <input type='mouse' bus='ps2'/>\n";
        xml = util.xml_append(xml, mouse);
        
        graphics = self.graphics.get_xml_config();
        xml = util.xml_append(xml, graphics);
        
#        sound = self.sound.get_xml_config();
#        xml = util.xml_append(xml, sound);
        
        video = self.video.get_xml_config();
        xml = util.xml_append(xml, video);
        
#        memballoon = self.memballoon.get_xml_config();
#        xml = util.xml_append(xml, memballoon);
        
        xml = util.xml_append(xml, "    </devices>");
        
        return xml;
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
